AWS Lambda PythonでSeleniumを使える環境を構築する
データアナリティクス事業本部のueharaです。
今回はAWS Lambda (Python)で、WebアプリケーションをテストするためのポータブルフレームワークであるSeleniumを使える環境を構築してみたいと思います。
バケットの準備
今回はLambda Layerを構築することになりますが、その資材をS3に配置するため、まずバケットを用意します。
AWSコンソールでサービスからS3を検索します。
「バケットを作成」から作業用のバケット「selenium-work」という名前のバケットを作成します。
その他の設定はデフォルトのままとします。
パッケージの用意
まず、Lambda (Python)でSeleniumを利用できるようにするために、各パッケージの用意を行います。 パッケージの用意には、無料で使えるサービスであるAWS CloudShellを利用します。
Seleniumのダウンロード
まず、東京リージョンを選択します。
次に、サービス欄からCloudShellを検索して、起動します。
起動ができたら、Pythonのデフォルトバージョンを確認してみます。
python --version
デフォルトではPython 2.7となっているようです。
デフォルトがPython 2.7だったので、今度は明示的にPython 3を指定してバージョンを確認してみます。
python3 --version
Python 3の場合、バージョンはPython 3.7となっていました。
今回はこのPython 3.7を利用したいと思います。
CloudShell上でpipを利用して、 ./python/lib/python3.7/site-packages
配下にSeleniumをダウンロードします。
pip3 install selenium==3.141.0 -t ./python/lib/python3.7/site-packages --use-feature=2020-resolver
※pipを利用した際に、boto3 1.26.11 requires botocore=1.29.11
というエラーが発生する可能性がありますが、今回のSeleniumのダウンロードに影響は無いので無視しても大丈夫です。
ダウンロードが完了すると、直下に python
ディレクトリができていると思うので、後でローカル環境にDLできるようにzip化しておきます。
zip -r python python
この時点でls
コマンドを利用すると、ディレクトリは以下のようになっていると思います。
chromedriver, headless-chromiumのダウンロード
次に、chromedriver, headless-chromiumを用意します。
まずは、CloudShell上で保存用ディレクトリを作成します。
mkdir headless
作成したディレクトリに移動します。
cd headless
次に、headless-chromiumのダウンロードを行います。
curl -SL https://github.com/adieuadieu/serverless-chrome/releases/download/v1.0.0-55/stable-headless-chromium-amazonlinux-2017-03.zip > headless-chromium.zip
ダウンロードが完了したら、展開します。
unzip -o headless-chromium.zip -d .
zipファイルの方はもう使わないので削除します。
rm headless-chromium.zip
続いて、chromedriverをダウンロードします。
先程ダウンロードしたheadless-chromiumのchromeバージョンは69
なので、chromedriverのバージョンは2.43
を利用します。
curl -SL https://chromedriver.storage.googleapis.com/2.43/chromedriver_linux64.zip > chromedriver.zip
先程と同じように、展開してzipファイルの方は削除を行います。
unzip -o chromedriver.zip -d . rm chromedriver.zip
ここまでの作業が完了したら、homeディレクトリに戻り、headless
ディレクトリをzip化します。
cd zip -r headless headless
この時点で再度ls
コマンドを利用すると、ディレクトリは以下のようになっていると思います。
用意したパッケージのS3へコピー
先の手順でzip化したファイル(python.zip, headless.zip)を、CloudShellからS3へコピーを行います。
CloudShell上ではAWS CLIのコマンドが使えますので、以下のコマンドでコピーを行います。
aws s3 cp python.zip s3://selenium-work
次のように表示されていればコピーは成功です。
同様に、headless.zipの方もS3へコピーを行います。
aws s3 cp headless.zip s3://selenium-work
Lambda Layersの構築
AWSコンソール上からAWS Lambdaのサービスに移動して、「レイヤー」を選択します。
seleniumレイヤーの作成
以下の設定で、seleniumレイヤーを作成します。
名前:selenium-layer
「Amazon S3 からファイルをアップロードする」を選択し、先の作業でS3へアップロードしたpython.zipのパス(s3://selenium-work/python.zip)を指定
ランタイム:Python3.7
headlessレイヤーの作成
以下の設定で、headlessレイヤーを作成します。
名前:headless-layer
「Amazon S3 からファイルをアップロードする」を選択し、先の作業でS3へアップロードしたheadless.zipのパス(s3://selenium-work/headless.zip)を指定
ランタイム:Python3.7
実行テスト
Lambda Layersの構築が完了したら、早速実行テストを行います。
関数の作成
AWS Lambdaのサービスから「関数の作成」を行います。
関数名はご自身のお好きな名前をつけ、ランタイムはPython 3.7を指定します。
関数名:uehara-test-func
ランタイム:Python 3.7
レイヤーの追加・設定変更
関数の作成が完了したら、下の方にある「レイヤー」から「レイヤーの追加」を行います。
カスタムレイヤーにチェックを入れ、「selenium-layer」を選択します。
selenium-layerの追加が完了したら、同様に、「headless-layer」の追加も行います。
以下のように、2つのレイヤーが追加されていれば成功です。
次に、「設定」の「一般設定」から、メモリサイズとタイムアウトをよしなに変更します。
※デフォルトのメモリ128MBとタイムアウト3秒では、Seleniumを動かすのが難しいため。
私の場合はメモリを256MBにして、タイムアウトを1分にしました。
コードの作成・デプロイ
ここまで作成ができたら、コードを作成しデプロイを行います。
作成したコードは以下の通りです。
from selenium import webdriver def lambda_handler(event, context): URL = "https://dev.classmethod.jp/" options = webdriver.ChromeOptions() # headless-chromiumのパスを指定 options.binary_location = "/opt/headless/headless-chromium" options.add_argument("--headless") options.add_argument('--single-process') options.add_argument('--disable-dev-shm-usage') options.add_argument("--no-sandbox") browser = webdriver.Chrome( # chromedriverのパスを指定 executable_path="/opt/headless/chromedriver", options=options ) browser.get(URL) title = browser.title browser.close() return title
作成したレイヤーは、Lambdaの実行環境の /opt
ディレクトリに展開されるので、headless-chroniumやchromedriverのパスはそれぞれ/opt/headless/headless-chromium
や/opt/headless/chromedriver
のように設定します。
※今回は後者で展開されるようにディレクトリを作成しているため
コンソール上でコードを入力し、「Deploy」ボタンを押すとデプロイを行うことができます。
テスト実行
テスト実行するために、「Test」ボタンからテストイベントを作成します。
今回のテスト実行にイベントJSONは本質的な意味を持たないので、テンプレートは「hello-world」のまま「MyTestEvent」という名前をつけてそのまま保存を行います。
保存が完了したら、「Test」ボタンを押してテストを行います。
実行後、次のようにDevelopersIOのタイトルが取得できていれば成功です。
最後に
今回はAWS Lambda PythonでSeleniumを使える環境を構築し、実行テストまで行い動作の確認を行ってみました。
LambdaでSeleniumを利用したいという方の参考になりましたら幸いです。